package ic.doc.co2nudge.client.widgets;

import java.util.Date;
import java.util.HashMap;
import java.util.TreeMap;

import ic.doc.co2nudge.client.utils.DataServiceFactory;
import ic.doc.co2nudge.client.utils.events.DataEvent;
import ic.doc.co2nudge.client.utils.events.DataLoadedEventHandler;
import ic.doc.co2nudge.client.utils.events.DataLoadedListener;
import ic.doc.co2nudge.client.utils.events.StatisticalDataEvent;
import ic.doc.co2nudge.client.utils.events.StatisticalDataLoadedListener;
import ic.doc.co2nudge.client.utils.events.StatisticalDataLodedHandler;
import ic.doc.co2nudge.shared.GraphType;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.i18n.shared.DateTimeFormat;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiTemplate;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Widget;

import com.google.gwt.visualization.client.AbstractDataTable;
import com.google.gwt.visualization.client.DataTable;
import com.google.gwt.visualization.client.AbstractDataTable.ColumnType;
import com.google.gwt.visualization.client.visualizations.corechart.AxisOptions;
import com.google.gwt.visualization.client.visualizations.corechart.LineChart;
import com.google.gwt.visualization.client.visualizations.corechart.Options;
import com.google.gwt.visualization.client.visualizations.corechart.PieChart;
import com.google.gwt.visualization.client.visualizations.corechart.BarChart;

public class StatisticsPanel extends Composite {
	
	private static StatisticsPanelUiBinder uiBinder = GWT
			.create(StatisticsPanelUiBinder.class);

	@UiTemplate("StatisticsPanel.ui.xml")
	interface StatisticsPanelUiBinder 
		extends UiBinder<Widget, StatisticsPanel> { }

	@UiField Button btnTransportTypes;
	@UiField Button btnCO2Rates;
	@UiField Button btnNumOfTrips;
	@UiField Button btnUsersCO2Rates;
	
	@UiField HorizontalPanel pnlChart;
	
	public StatisticsPanel() {
		
		initWidget(uiBinder.createAndBindUi(this));
		
		DataServiceFactory.addStatisticalDataLoadedListener (
				new StatisticalDataLodedHandler() {
					
					@Override
					public void dataLoaded(StatisticalDataEvent e) {
					
						GraphType graphType=e.getGraphType();
						 HashMap<String, Double> data=
							(HashMap<String, Double>)e.getStatData();
						
						generateGraph(graphType, data);
					}
				});
		
		ClickHandler clickHandler=new ClickHandler(){

			@Override
			public void onClick(ClickEvent e) {

					GraphType graphType=GraphType.TRANSPORT_TYPES;
				
					if (e.getSource()==btnCO2Rates){
						graphType=GraphType.CO2_RATE;
					} else
					if (e.getSource()==btnNumOfTrips){
						graphType=GraphType.NUM_OF_TRIPS;
					}else
					if (e.getSource()==btnUsersCO2Rates){
						graphType=GraphType.USERS_CO2_RATES;
					}
					
					DataServiceFactory.loadStatisticalData(graphType);
				};
		};
		
		btnTransportTypes.addClickHandler(clickHandler);
		btnCO2Rates.addClickHandler(clickHandler);
		btnNumOfTrips.addClickHandler(clickHandler);
		btnUsersCO2Rates.addClickHandler(clickHandler);
	}
	
	private void generateGraph(GraphType type, 
			 HashMap<String, Double> data) {

		pnlChart.clear();
		
		switch(type){
		 
			case TRANSPORT_TYPES:{
				
				PieChart pchrtTransportTypes=
					new PieChart(createDataTable(type, data),
							createOptions(type));
				
				pchrtTransportTypes.setVisible(true);
			
				pnlChart.add(pchrtTransportTypes);
				pnlChart.setVisible(true);
				
			}break;
			case CO2_RATE:{
				BarChart bchrtCO2Rates=
					new BarChart(createDataTable(type, data),
							createOptions(type));
				pnlChart.add(bchrtCO2Rates);
				
			}break;	
			case NUM_OF_TRIPS:{
				BarChart bchrtNumOfPeople=
					new BarChart(createDataTable(type, data),
							createOptions(type));
				pnlChart.add(bchrtNumOfPeople);
				
			}break;		
			case USERS_CO2_RATES:{
				LineChart lchrtUsers=
					new LineChart(createDataTable(type, data),
							createOptions(type));
				pnlChart.add(lchrtUsers);
				
			}break;
		}
	}
	
	private Options createOptions(GraphType type) {
		
		Options options=Options.create();
		options.setWidth(500);
		options.setHeight(300);
		options.setBackgroundColor("white");
		options.setFontSize(11D);
		options.setFontName("Tahoma");
		options.setGridlineColor("lightgrey");
		options.setLineWidth(1);
		
		AxisOptions vaxisOptions=
			AxisOptions.create();
		AxisOptions haxisOptions=
			AxisOptions.create();
		
		options.setAxisTitlesPosition("center");
		
		switch(type){
			case TRANSPORT_TYPES: {
				options
					.setTitle("Transport types distribution");
			} break;
			case CO2_RATE: {
				options
					.setTitle("Carbon emission rates");
			} break;
			case NUM_OF_TRIPS: {
				
			} break;
			case USERS_CO2_RATES: {
				
			} break;
		}
		
		options.setVAxisOptions(vaxisOptions);
		options.setHAxisOptions(haxisOptions);
		
		return options;
	}
	
	private AbstractDataTable createDataTable(GraphType type, 
			 HashMap<String, Double> data) {
		
		DataTable table=DataTable.create();
		
		switch(type) {
		
			case TRANSPORT_TYPES: {
					table.addColumn(ColumnType.STRING, "Transport type");
					table.addColumn(ColumnType.NUMBER, "Percentage");
					
					table.addRows(data.size());
					
					try {
						int curIndex=0;
						
						for (String key: data.keySet()) {	
							table.setValue(curIndex, 0,	key);
							table.setValue(curIndex, 1, (Double)data.get(key));
							curIndex++;
						}
					} catch(Exception ex) {
						Window.alert("error in datatable creation");
						return null;
					}
					
					
			} break;
			case CO2_RATE: {
					table.addColumn(ColumnType.STRING, "Date");
					table.addColumn(ColumnType.NUMBER, "Carbon emission");
					
					TreeMap fetchedData=new TreeMap();
					for (String key: data.keySet()) {
						fetchedData.put( DateTimeFormat
								.getFormat("MM-yyyy").parse(key), 
								(Double)data.get(key));
					}
					
					table.addRows(fetchedData.size());
					
					try {
						int curIndex=0;
						
						for (Object key: fetchedData.keySet()) {	
							table.setValue(curIndex, 0,	DateTimeFormat
									.getFormat("MMM").format((Date)key));
							table.setValue(curIndex, 1, 
									(Double)fetchedData.get(key));
							curIndex++;
						}
					} catch(Exception ex) {
						Window.alert("error in datatable creation");
						return null;
					}
			} break;
			case NUM_OF_TRIPS: {
				
				
			} break;
			case USERS_CO2_RATES: {
				
				
			} break;
		}
		
		return table;	
	}
}